//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#ifndef BLOB_NET_H
#define BLOB_NET_H

/* Ethernet */
#define ETH_ALEN 6
#define ETHPROTO_IP 0x0800
#define ETHPROTO_ARP 0x0806
#define ETHPROTO_RARP 0x8035

/* IP */
#define IPPROTO_ICMP 1
#define IPPROTO_UDP 17

#define IP_DF  0x4000
#define IP_MF  0x2000
#define IP_OFFMASK 0x1fff

#define IPVERSION  4
#define MAXTTL  8

/* ARP */
#define ARPHDR_ETHER 1

#define ARP_REQUEST 1
#define ARP_REPLY 2
#define ARP_REVREQUEST 3
#define ARP_REVREPLY 4

/* ICMP */
#define ICMP_MINLEN 8

#define ICMP_ECHOREPLY 0
#define ICMP_UNREACH 3
#define ICMP_ECHO 8

struct etherhdr
{
    unsigned char  eh_dhost[ETH_ALEN];
    unsigned char  eh_shost[ETH_ALEN];
    unsigned short  eh_proto;
} __attribute__ ((__packed__));

struct in_addr
{
    unsigned char addr[4];
} __attribute__ ((__packed__));

struct iphdr
{
    unsigned char  ip_hl : 4,
                  ip_v  : 4;
    unsigned char  ip_tos;
    short   ip_len;
    unsigned short ip_id;
    short  ip_off;
    unsigned char ip_ttl;
    unsigned char  ip_p;
    unsigned short ip_sum;
    struct in_addr ip_src, ip_dst;
} __attribute__ ((__packed__));

struct udphdr
{
    unsigned short  uh_sport;
    unsigned short  uh_dport;
    short  uh_len;
    unsigned short uh_sum;
} __attribute__ ((__packed__));

struct udp_port
{
    unsigned short port;
    int (*handler)();
};

struct icmphdr
{
    unsigned char type;
    unsigned char code;
    unsigned short cksum;
    union
    {
        struct in_addr gwaddr;
        struct
        {
            unsigned short id;
            unsigned short seq;
        } idseq;
        struct
        {
            unsigned short  __unused;
            unsigned short mtu;
        } mtu;
    } body;
} __attribute__ ((__packed__));

struct arphdr
{
    unsigned short ar_hrd;
    unsigned short  ar_pro;
    unsigned char ar_hln;
    unsigned char ar_pln;
    unsigned short ar_op;
} __attribute__ ((__packed__));

struct ether_arp
{
    struct arphdr ea_hdr;
    unsigned char arp_sha[6];
    unsigned char arp_spa[4];
    unsigned char arp_tha[6];
    unsigned char  arp_tpa[4];
} __attribute__ ((__packed__));

#define BUFSZ 2048

struct mybuf
{
    int len;
    unsigned char buf[BUFSZ];

    struct iphdr *ip;
    struct arphdr *arp;
    struct udphdr *udp;
    struct etherhdr *ether;
    struct ether_arp *etharp;
};

#define ntohs(x) ( ( ( (x) & 0xff ) << 8 ) |  ( ((x)>> 8) & 0xff) )
#define htons(x) ( ( ( (x) & 0xff ) << 8 ) |  ( ((x)>> 8) & 0xff) )

struct mybuf *bget(int io);
void net_rx();
void net_reset();

void net_init(void);
void net_test(void);
int cmd_tftp(u8* filename, u8* dest_address);
int cmd_ifconfig(u8* conf, u8* address);

#endif
